/*
 * 项目名称:    wms-server-jeecg
 * 创建人员:    gongwenkai
 * 创建时间:    2023-09-26
 */
package org.jeecg.modules.flow.callback.outbound.task;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceipt;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceiptMaterial;
import org.jeecg.modules.business.doc.outbound.service.IWmsOutReceiptService;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTask;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTaskMaterial;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskMaterialService;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskService;
import org.jeecg.modules.business.repertory.entity.vo.RepertoryDocumentVO;
import org.jeecg.modules.business.repertory.entity.vo.RepertoryVO;
import org.jeecg.modules.business.repertory.service.IWmsRepertoryService;
import org.jeecg.modules.flow.callback.enums.DocumentStatusEnum;
import org.jeecg.modules.flow.callback.enums.OutboundStatusEnum;
import org.jeecg.modules.flow.callback.outbound.util.CommonOutboundUtil;
import org.jeecg.modules.flow.record.entity.WmsFlowRecord;
import org.jeecg.modules.flow.sys.common.BaseCustomBeanRun;
import org.jeecg.modules.flow.sys.entity.dto.BaseFlowDto;
import org.jeecg.modules.flow.sys.entity.dto.WorkFlowInfoDto;
import org.jeecg.modules.flow.sys.service.WorkFlowService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 横剪叫料板 出库 回调Bean
 *
 * @author gongwenkai
 * @version 1.0.0
 * @since 2023-09-26
 */
@RequiredArgsConstructor
@Component
public class OutBoundTaskHJJLBOutBean<T> extends BaseCustomBeanRun<T> {


    private final IWmsOutReceiptTaskService wmsOutReceiptTaskService;

    private final IWmsOutReceiptTaskMaterialService wmsOutReceiptTaskMaterialService;

    private final IWmsOutReceiptService wmsOutReceiptService;

    private final IWmsRepertoryService wmsRepertoryService;

    private final WorkFlowService workFlowService;

    private final CommonOutboundUtil commonOutboundUtil;

    /**
     * 业务逻辑 横剪叫料板 出库
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void actureRun() {
        BaseFlowDto baseFlowDto = this.getBaseFlowDto();
        String taskId = baseFlowDto.getInfoId();
        //自动创建出库单
        autoCreateOrder(taskId);
        wmsOutReceiptTaskService.update(new LambdaUpdateWrapper<WmsOutReceiptTask>()
                .set(WmsOutReceiptTask::getDocumentStatus, DocumentStatusEnum.COMPLETE.getCode())
                .eq(WmsOutReceiptTask::getId, taskId));
        // 当前前端调用业务需要你返回的
        baseFlowDto.setResult(Result.OK());
        // id是保存业务记录的id。用于生成业务流程信息记录
        baseFlowDto.setInfoId(taskId);
    }


    /**
     * 自动创建出库单
     */
    public void autoCreateOrder(String taskId) {

        WmsOutReceiptTask receiptTask = wmsOutReceiptTaskService.getById(taskId);
        List<WmsOutReceiptTaskMaterial> receiptTaskMaterialList = wmsOutReceiptTaskMaterialService.list(new LambdaUpdateWrapper<WmsOutReceiptTaskMaterial>()
                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, taskId)
        );
        WmsOutReceipt wmsOutReceipt = new WmsOutReceipt();
        wmsOutReceipt.setSysOrgCode(receiptTask.getSysOrgCode());
        wmsOutReceipt.setOrganization(receiptTask.getOrganization());
        wmsOutReceipt.setDocumentType(receiptTask.getDocumentType());
        wmsOutReceipt.setDocumentCode((String) FillRuleUtil.executeRule("ck_rule", null));
        wmsOutReceipt.setOwnerType(receiptTask.getOwnerType());
        wmsOutReceipt.setBusinessDate(null);
        wmsOutReceipt.setOwner(receiptTask.getOwner());
        wmsOutReceipt.setWarehouseDirection(receiptTask.getWarehouseDirection());
        wmsOutReceipt.setCustomer(receiptTask.getCustomer());
        wmsOutReceipt.setDocumentStatus(null);
        wmsOutReceipt.setWmsBasicWarehouseGroupId(receiptTask.getWmsBasicWarehouseGroupId());
        wmsOutReceipt.setRemark(null);
        wmsOutReceipt.setWarehouseKeeper(receiptTask.getWarehouseKeeper());
        wmsOutReceipt.setOutDate(new Date());
        wmsOutReceipt.setHasChild(1);
        wmsOutReceipt.setWmsOutReceiptTaskId(receiptTask.getId());

        List<WmsOutReceiptMaterial> wmsOutReceiptMaterialList = receiptTaskMaterialList.stream().map(o -> {
            WmsOutReceiptMaterial wmsOutReceiptMaterial = new WmsOutReceiptMaterial();
            wmsOutReceiptMaterial.setSysOrgCode(o.getSysOrgCode());
            wmsOutReceiptMaterial.setWmsBasicMaterialId(o.getWmsBasicMaterialId());
            wmsOutReceiptMaterial.setBatchCode(o.getBatchCode());
            wmsOutReceiptMaterial.setPayableQuantity(o.getPlanQuantity());
            wmsOutReceiptMaterial.setOutboundQuantity(o.getPlanQuantity());
            wmsOutReceiptMaterial.setWmsBasicWarehouseId(o.getWmsBasicWarehouseId());
            wmsOutReceiptMaterial.setWmsBasicWarehouseAreaId(o.getWmsBasicWarehouseAreaId());
            wmsOutReceiptMaterial.setWmsBasicWarehouseAreaLocationId(o.getWmsBasicWarehouseAreaLocationId());
            wmsOutReceiptMaterial.setAssistQuantity(Objects.isNull(o.getAssistQuantity()) ? null : o.getAssistQuantity());
            wmsOutReceiptMaterial.setSteelCoilNumber(o.getSteelCoilNumber());
            wmsOutReceiptMaterial.setOutsideDiameter(ObjectUtil.isEmpty(o.getOutsideDiameter()) ? null : o.getOutsideDiameter());
            wmsOutReceiptMaterial.setWidth(ObjectUtil.isEmpty(o.getWidth()) ? null : o.getWidth());
            wmsOutReceiptMaterial.setLength(ObjectUtil.isEmpty(o.getLength()) ? null : o.getLength());
            wmsOutReceiptMaterial.setThickness(ObjectUtil.isEmpty(o.getThickness()) ? null : o.getThickness());
            wmsOutReceiptMaterial.setShopSign(o.getShopSign());
            wmsOutReceiptMaterial.setAppearanceGrade(o.getAppearanceGrade());
            wmsOutReceiptMaterial.setIronLoss(o.getIronLoss());
            wmsOutReceiptMaterial.setMeasuredThickness(Objects.isNull(o.getMeasuredThickness()) ? null : o.getMeasuredThickness());
            wmsOutReceiptMaterial.setMeasuredIronLoss(o.getMeasuredIronLoss());
            wmsOutReceiptMaterial.setScore(o.getScore());
            wmsOutReceiptMaterial.setOriginalWeight(Objects.isNull(o.getOriginalWeight()) ? null : o.getOriginalWeight());
            wmsOutReceiptMaterial.setMeasuredWeight(Objects.isNull(o.getMeasuredWeight()) ? null : o.getMeasuredWeight());
            wmsOutReceiptMaterial.setVehicle(null);
            wmsOutReceiptMaterial.setSerialNumber(o.getSerialNumber());
            wmsOutReceiptMaterial.setSaleOrderNumber(o.getSaleOrderNumber());
            wmsOutReceiptMaterial.setSaleOrderLineNumber(o.getSaleOrderLineNumber());
            wmsOutReceiptMaterial.setProductNumber(o.getProductNumber());
            wmsOutReceiptMaterial.setProductLineNumber(o.getProductLineNumber());
            wmsOutReceiptMaterial.setUpstreamDocuments("出库任务");
            wmsOutReceiptMaterial.setUpstreamNumber(receiptTask.getDocumentCode());
            wmsOutReceiptMaterial.setUpstreamLineNumber(o.getUpstreamLineNumber());
            wmsOutReceiptMaterial.setOriginalSystemNumber(o.getOriginalSystemNumber());
            wmsOutReceiptMaterial.setOriginalSystemLineNumber(o.getOriginalSystemLineNumber());
            wmsOutReceiptMaterial.setGrossWeight(Objects.isNull(o.getGrossWeight()) ? null : o.getGrossWeight());
            wmsOutReceiptMaterial.setPayableQuantityAssist(o.getOutboundQuantityAssist());
            wmsOutReceiptMaterial.setOutboundQuantityAssist(o.getOutboundQuantityAssist());
            wmsOutReceiptMaterial.setWmsOutReceiptId(null);
            wmsOutReceiptMaterial.setWmsBasicUnitId(o.getWmsBasicUnitId());
            wmsOutReceiptMaterial.setMaterialCode(o.getMaterialCode());
            wmsOutReceiptMaterial.setSpecificationModel(o.getSpecificationModel());
            wmsOutReceiptMaterial.setIsMergeRoll(o.getIsMergeRoll());
            wmsOutReceiptMaterial.setInputBatchCode(o.getInputBatchCode());
            wmsOutReceiptMaterial.setMotherBatchCode(o.getMotherBatchCode());
            wmsOutReceiptMaterial.setPillar(o.getPillar());
            wmsOutReceiptMaterial.setMaterialDirection(o.getMaterialDirection());
            wmsOutReceiptMaterial.setStationNum(o.getStationNum());
            wmsOutReceiptMaterial.setProductModel(o.getSpecificationModel());
            wmsOutReceiptMaterial.setProductType(o.getProductType());
            wmsOutReceiptMaterial.setWmsOutReceiptTaskMaterialId(o.getId());
            return wmsOutReceiptMaterial;
        }).collect(Collectors.toList());

        String receiptId = wmsOutReceiptService.saveMain(wmsOutReceipt, wmsOutReceiptMaterialList, true);
        wmsOutReceiptTaskService.update(new LambdaUpdateWrapper<WmsOutReceiptTask>()
                .set(WmsOutReceiptTask::getOutboundStatus, OutboundStatusEnum.ALL.getCode())
                .set(WmsOutReceiptTask::getDocumentStatus, DocumentStatusEnum.COMPLETE.getCode())
                .eq(WmsOutReceiptTask::getId, taskId)
        );
        wmsOutReceiptService.update(new LambdaUpdateWrapper<WmsOutReceipt>()
                .set(WmsOutReceipt::getDocumentStatus, DocumentStatusEnum.COMPLETE.getCode())
                .eq(WmsOutReceipt::getId, receiptId)
        );
        List<RepertoryVO> collect = wmsOutReceiptMaterialList.stream().map(o -> {
            RepertoryVO repertoryVO = BeanUtil.copyProperties(o, RepertoryVO.class);
            repertoryVO.setStockQuantity(o.getOutboundQuantity());
            return repertoryVO;
        }).collect(Collectors.toList());
        RepertoryDocumentVO repertoryDocumentVO = new RepertoryDocumentVO();
        repertoryDocumentVO.setInvoicesId(receiptId);
        repertoryDocumentVO.setDocumentType(2);
        repertoryDocumentVO.setRepertoryVOS(collect);
        //扣除即时库存
        wmsRepertoryService.reduce(repertoryDocumentVO);
        //更新任务物料信息
        receiptTaskMaterialList.stream().forEach(o -> {
            LambdaUpdateWrapper<WmsOutReceiptTaskMaterial> updateWrapper = new LambdaUpdateWrapper<WmsOutReceiptTaskMaterial>();
            updateWrapper
                    .set(WmsOutReceiptTaskMaterial::getHasOutboundQuantity, o.getPlanQuantity())
                    .set(WmsOutReceiptTaskMaterial::getUnoutboundQuantity, BigDecimal.ZERO)
                    .set(WmsOutReceiptTaskMaterial::getOutboundStatus, OutboundStatusEnum.ALL.getCode())
                    .eq(WmsOutReceiptTaskMaterial::getId, o.getId());
            wmsOutReceiptTaskMaterialService.update(updateWrapper);
        });
        //自动更新出库单节点
        WorkFlowInfoDto workFlowInfoDto = new WorkFlowInfoDto();
        workFlowInfoDto.setBusinessType("outbound_type");
        workFlowInfoDto.setDocumentType(receiptTask.getDocumentType());
        List<WmsFlowRecord> wmsFlowRecordList = workFlowService.workFlowInfo(workFlowInfoDto);
        if (!CollectionUtil.isEmpty(wmsFlowRecordList)) {
            WmsFlowRecord lastFlowRecord = CollectionUtil.getLast(wmsFlowRecordList);
            BaseFlowDto lastFlowDto = new BaseFlowDto();
            lastFlowDto.setCode(lastFlowRecord.getFlowCode());
            lastFlowDto.setBusinessType("outbound_type");
            lastFlowDto.setDocumentType(receiptTask.getDocumentType());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", receiptId);
            lastFlowDto.setData(jsonObject);
            workFlowService.commit(lastFlowDto);
        }
    }
}
